home *** CD-ROM | disk | FTP | other *** search
/ Info-Mac 4 / Info_Mac IV CD-ROM (Pacific HiTech Inc.)(August 1994).iso / Development / General / DR1.#1 PPC C⁄C++ ƒ / C++ Runtime ƒ / CPlusPlusLib.cp next >
Text File  |  1994-02-09  |  6KB  |  250 lines

  1.  
  2. /*
  3.  *    CPlusLib.cp        -    C++ Runtime Support Routines for Metrowerks C++ (PowerPC)
  4.  *
  5.  *    Copyright © 1993 metrowerks inc. All Rights Reserved.
  6.  *
  7.  */
  8.  
  9.  
  10. #include <stdlib.h>
  11.  
  12.  
  13.     /*    private types    */
  14.  
  15. typedef void (*ConstructorDestructor)(void *, int);
  16.  
  17. typedef struct DestructorChain {
  18.     struct DestructorChain    *next;            /*    pointer to next destructor chain element    */
  19.     ConstructorDestructor    destructor;        /*    pointer to destructor function    */
  20.     void                    *object;        /*    pointer to memory location (0L: element is marker)    */
  21. } DestructorChain;
  22.  
  23. typedef struct PTMF {
  24.     long    this_delta;                        /*    delta to this pointer    */
  25.     long    vtbl_offset;                    /*    offset in vtable (-1: not a virtual function)    */
  26.     union {
  27.         void    *func_addr;                    /*    nonvirtual function address    */
  28.         long    ventry_offset;                /*    offset of virtual function entry in vtable    */
  29.     }    func_data;
  30. } PTMF;
  31.  
  32.  
  33.     /*    private data        */
  34.  
  35. static DestructorChain    *__global_destructor_chain;    /*    chain of global objects that need destruction    */
  36. static DestructorChain    *__local_destructor_chain;    /*    chain of local objects that need destruction    */
  37.  
  38.  
  39.     /*    prototypes    */
  40.  
  41. extern "C" {
  42.  
  43. PTMF *__ptmf_cast(long offset, const PTMF *ptmfrom, PTMF *ptmto);
  44.  
  45. void *__register_global_object(void *object, ConstructorDestructor destructor, DestructorChain *regmem);
  46. void *__register_local_object(void *object, ConstructorDestructor destructor, DestructorChain *regmem);
  47.  
  48. void __destroy_local_objects(DestructorChain *lastregmem);
  49. void __destroy_local_chain(void);
  50. void __destroy_global_chain(void);
  51.  
  52. void *__new_arr(ConstructorDestructor constructor, size_t objectsize, size_t nobjects);
  53. void __del_arr(void *memptr, ConstructorDestructor destructor);
  54. void __dc_arr(void *memptr, ConstructorDestructor constructordestructor, short objectsize, short nobjects);
  55.  
  56. }
  57.  
  58.  
  59. /*
  60.  *    __ptmf_cast    -    copy/cast a pointer-to-member-function
  61.  *
  62.  */
  63.  
  64. PTMF *__ptmf_cast(long offset, const PTMF *ptmfrom, PTMF *ptmto)
  65. {
  66.     ptmto->this_delta = ptmfrom->this_delta+offset;
  67.     
  68.     if(ptmfrom->vtbl_offset >= 0L) {        //    virtual function pointer
  69.         ptmto->vtbl_offset = ptmfrom->vtbl_offset + offset;
  70.         ptmto->func_data.ventry_offset = ptmfrom->func_data.ventry_offset;
  71.     }
  72.     else {                                //    nonvirtual function pointer
  73.         ptmto->vtbl_offset = -1L;
  74.         ptmto->func_data.func_addr = ptmfrom->func_data.func_addr;
  75.     }
  76.     
  77.     return(ptmto);
  78. }
  79.  
  80.  
  81. /*
  82.  *    __register_global_object    -    register a global object for later destruction
  83.  *
  84.  *    We add the object and its destructor to a chain of (global object,destructor) pairs.
  85.  *    The standard termination routine will traverse this list and destroy all objects
  86.  *    whenever/however an application terminates.
  87.  *
  88.  */
  89.  
  90. void *__register_global_object(void *object, ConstructorDestructor destructor, DestructorChain *regmem)
  91. {
  92.     regmem->next = __global_destructor_chain;
  93.     regmem->destructor = destructor;
  94.     regmem->object = object;
  95.     __global_destructor_chain = regmem;
  96.     return(object);
  97. }
  98.  
  99.  
  100. /*
  101.  *    __register_local_object    -    register a local object for later destruction
  102.  *
  103.  *    We add the object and its destructor to a chain of (local object,destructor) pairs.
  104.  *    These local objects are destroyed at the end of a scope or as part of stack unwinding
  105.  *    when an exception is thrown.
  106.  *
  107.  */
  108.  
  109. void *__register_local_object(void *object, ConstructorDestructor destructor, DestructorChain *regmem)
  110. {
  111.     regmem->next = __local_destructor_chain;
  112.     regmem->destructor = destructor;
  113.     regmem->object = object;
  114.     __local_destructor_chain = regmem;
  115.     return(object);
  116. }
  117.  
  118.  
  119. /*
  120.  *    __destroy_local_objects    -    destroy some local objects
  121.  *
  122.  *    Call the destructor for every object in the local object chain up to (and
  123.  *    including) 'lastregmem'.
  124.  *
  125.  */
  126.  
  127. void __destroy_local_objects(DestructorChain *lastregmem)
  128. {
  129.     DestructorChain *chain;
  130.     void *object;
  131.     
  132.     while ((chain = __local_destructor_chain) != 0) {
  133.         if ((object = chain->object) != 0)
  134.             (*chain->destructor)(object, -1);
  135.         __local_destructor_chain = chain->next;
  136.         if (chain == lastregmem)
  137.             break;
  138.     }
  139. }
  140.  
  141.  
  142. /*
  143.  *    __destroy_local_chain    -    destroy all local objects
  144.  *
  145.  *    Call the destructor for every object in the local object chain.
  146.  *
  147.  */
  148.  
  149. void __destroy_local_chain(void)
  150. {
  151.     DestructorChain *chain;
  152.     void *object;
  153.     
  154.     while ((chain = __local_destructor_chain) != 0) {
  155.         if ((object = chain->object) != 0)
  156.             (*chain->destructor)(object, -1);
  157.         __local_destructor_chain = chain->next;
  158.     }
  159. }
  160.  
  161.  
  162. /*
  163.  *    __destroy_global_chain    -    destroy all global objects
  164.  *
  165.  *    Call the destructor for every object in the global object chain.
  166.  *
  167.  */
  168.  
  169. void __destroy_global_chain(void)
  170. {
  171.     DestructorChain *chain;
  172.     void *object;
  173.     
  174.     while ((chain = __global_destructor_chain) != 0) {
  175.         if ((object = chain->object) != 0)
  176.             (*chain->destructor)(object, -1);
  177.         __global_destructor_chain = chain->next;
  178.     }
  179. }
  180.  
  181.  
  182. /*
  183.  *    __new_arr    -    allocate and construct an array of objects
  184.  *
  185.  *    We allocate space for an array of 'nobjects' elements of size 'objectsize', and
  186.  *    space to store 'nobjects' and 'objectsize' (for later deletion). Then we call
  187.  *    the given constructor for each object in the array.
  188.  *
  189.  */
  190.  
  191. void *__new_arr(ConstructorDestructor constructor, size_t objectsize, size_t nobjects)
  192. {
  193.     char *memptr, *p;
  194.     
  195.     if ((memptr = (char *) ::operator new(2*sizeof(size_t) + nobjects*objectsize)) != 0) {
  196.         memptr += 2*sizeof(size_t);
  197.         ((size_t *) memptr)[-2] = objectsize;
  198.         ((size_t *) memptr)[-1] = nobjects;
  199.         if (constructor) {
  200.             for (p = memptr; nobjects--; p += objectsize)
  201.                 (*constructor)(p, 1);
  202.         }
  203.     }
  204.     
  205.     return(memptr);
  206. }
  207.  
  208.  
  209. /*
  210.  *    __del_arr    -    destroy and deallocate an array of objects
  211.  *
  212.  *    We use the previously saved 'nobjects' and 'objectsize' values to call the
  213.  *    destructor for each element of the array. Then we delete the space allocated
  214.  *    to it.
  215.  *
  216.  */
  217.  
  218. void __del_arr(void *memptr, ConstructorDestructor destructor)
  219. {
  220.     size_t nobjects, objectsize;
  221.     char *p;
  222.     
  223.     if (memptr) {
  224.         if (destructor) {
  225.             objectsize = ((size_t *) memptr)[-2];
  226.             nobjects = ((size_t *) memptr)[-1];
  227.             for (p = (char *) memptr; nobjects--; p += objectsize)
  228.                 (*destructor)(p, -1);
  229.         }
  230.         ::delete (&((size_t *) memptr)[-2]);
  231.     }
  232. }
  233.  
  234.  
  235. /*
  236.  *    __dc_arr    -    construct or destroy a statically allocated array of objects
  237.  *
  238.  *    We call the given constructor or destructor for each of 'nobjects' elements of size
  239.  *    'objectsize' in a statically allocated array.
  240.  *
  241.  */
  242.  
  243. void __dc_arr(void *memptr, ConstructorDestructor constructordestructor, short objectsize, short nobjects)
  244. {
  245.     char *p;
  246.     
  247.     for (p = (char *) memptr; nobjects--; p += objectsize)
  248.         (*constructordestructor)(p, -1);
  249. }
  250.